package com.intco.ait.quotation.api.infrastructure.service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.intco.ait.quotation.api.common.model.BomInfoDTO;
import com.intco.ait.quotation.api.common.model.SkuVo;
import com.intco.ait.quotation.api.common.model.request.SkuSearch;
import com.intco.ait.quotation.api.common.utils.UIDGenerator;
import com.intco.ait.quotation.api.infrastructure.mybatis.entity.BomDetailDo;
import com.intco.ait.quotation.api.infrastructure.mybatis.entity.BomTemplateDo;
import com.intco.ait.quotation.api.infrastructure.mybatis.entity.SkuDo;
import com.intco.ait.quotation.api.infrastructure.mybatis.service.BomDetailService;
import com.intco.ait.quotation.api.infrastructure.mybatis.service.SkuService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SkuDataService {

    @Autowired
    private SkuService skuService;

    @Autowired
    private BomDetailService bomDetailService;

    @Autowired
    private BomService bomService;

    @Autowired
    private UIDGenerator uidGenerator;

    public Page<SkuVo> search(SkuSearch skuSearch) {
        QueryChainWrapper<SkuDo> query = skuService.query();
        if (StringUtils.isNotBlank(skuSearch.getProductType())) {
            query.eq("product_type", skuSearch.getProductType());
        }
        if (StringUtils.isNotBlank(skuSearch.getStatus())) {
            query.eq("status", skuSearch.getStatus());
        }
        if (StringUtils.isNotBlank(skuSearch.getInvCode())) {
            query.eq("inv_code", skuSearch.getInvCode());
        } else if (StringUtils.isNotBlank(skuSearch.getInvName())) {
            query.like("inv_name", skuSearch.getInvName());
        }
        Page<SkuDo> skuDoPage = query.orderByDesc("insert_time")
                .page(new Page<>(skuSearch.getPage(), skuSearch.getPageSize()));
        List<SkuVo> skuVoS = skuDoPage.getRecords().stream().map(skuDo -> {
            SkuVo skuVo = new SkuVo();
            skuVo.setId(skuDo.getId());
            skuVo.setProductType(skuDo.getProductType());
            skuVo.setInvCode(skuDo.getInvCode());
            skuVo.setName(skuDo.getName());
            skuVo.setPic(skuDo.getPic());
            skuVo.setBomS(bomService.getBomSForSku(JSON.parseArray(skuDo.getBomDetailIds(), Long.class)));
            skuVo.setStatus(skuDo.getStatus());
            skuVo.setPort(skuDo.getPort());
            skuVo.setCutting(skuDo.getCutting());
            skuVo.setLabor(skuDo.getLabor());
            skuVo.setCreateTime(skuDo.getInsertTime());
            skuVo.setUpdateTime(skuDo.getUpdateTime());
            return skuVo;
        }).collect(Collectors.toList());

        return new Page<SkuVo>(skuDoPage.getCurrent(), skuDoPage.getSize(), skuDoPage.getTotal())
                .setRecords(skuVoS);
    }

    public void createSku(SkuVo skuVo) {
        boolean exist = skuService.query().eq("name", skuVo.getName()).exists();
        if (exist) {
            throw new IllegalArgumentException("Sku name already exists");
        }
        SkuDo skuDo = new SkuDo();
        skuDo.setId(uidGenerator.nextId());
        skuDo.setInvCode(skuVo.getInvCode());
        skuDo.setName(skuVo.getName());
        skuDo.setProductType(skuVo.getProductType());
        skuDo.setPic(skuVo.getPic());
        List<BomInfoDTO> bomS = skuVo.getBomS();
        List<Long> bomIds = new ArrayList<>();
        bomS.forEach(bomInfo -> {
            BomTemplateDo existBom = bomService.getBomTemplateByName(bomInfo.getBom().getName());
            Long newBomId = null;
            if (existBom == null) {
                newBomId = bomService.creatBom(bomInfo.getBom());
            }
            Long bomId = Objects.isNull(newBomId) ? existBom.getId() : newBomId;
            long bomDetailId = bomService.initBomDetailId(bomInfo, skuDo.getId(), bomId);
            bomIds.add(bomDetailId);
        });
        skuDo.setBomDetailIds(JSON.toJSONString(bomIds));
        skuService.save(skuDo);
    }

    public void update(SkuVo skuVo) {
        SkuDo skuDo = skuService.getById(skuVo.getId());
        if (skuDo == null) {
            throw new IllegalArgumentException("Sku does not exist");
        }
        List<BomInfoDTO> bomS = skuVo.getBomS();
        List<BomDetailDo> bomDetailDos = bomDetailService.query().eq("belong_id", skuVo.getId()).list();
        Set<Long> newBomIdS = bomService.handleAddBomForBelong(skuVo.getId(), bomS, bomDetailDos);
        skuDo.setPort(skuVo.getPort());
        skuDo.setCutting(skuVo.getCutting());
        skuDo.setLabor(skuVo.getLabor());
        skuDo.setBomDetailIds(JSON.toJSONString(newBomIdS));
        skuDo.setStatus(skuVo.getStatus());
        skuDo.setUpdateTime(new Date());
        skuService.updateById(skuDo);
    }

    public List<String> getProducts() {
        return skuService.query().select("distinct product_type").list()
                .stream().map(SkuDo::getProductType).collect(Collectors.toList());
    }
}
